﻿using System;
using System.Messaging;
using System.Text.RegularExpressions;

namespace BTS.Testing.TraceMonitor.BizUnitSteps.Helpers
{
        /// <summary>
        /// Wrappers the event trace management for the testing utilities
        /// </summary>
        public class EventTraceManager
        {
            /// <summary>
            /// Checks for the next event on the queue
            /// </summary>
            /// <param name="regEx"></param>
            /// <param name="includeBodyCompare"></param>
            /// <param name="timeoutSeconds"></param>
            /// <param name="deleteAfterFound"></param>
            /// <param name="queuePath"></param>
            /// <returns></returns>
            public static bool PeekForNextEvent(string regEx, bool includeBodyCompare, int timeoutSeconds, bool deleteAfterFound, string queuePath)
            {
                var found = false;
                try
                {
                    var queue = new MessageQueue(queuePath);
                    var msg = queue.Peek(new TimeSpan(0, 0, timeoutSeconds));
                    if (msg != null)
                    {
                        if (Regex.IsMatch(msg.Label, regEx, RegexOptions.IgnoreCase))
                        {
                            Console.WriteLine(string.Format("Matching label: {0}", msg.Label));
                            found = true;
                        }

                        if (!found && includeBodyCompare)
                        {
                            msg.Formatter = new ActiveXMessageFormatter();
                            var body = msg.Body as string;
                            if (body != null)
                                if (Regex.IsMatch(body, regEx, RegexOptions.IgnoreCase | RegexOptions.Multiline))
                                {
                                    Console.WriteLine(string.Format("Matching body: {0}", msg.Label));
                                    found = true;
                                }
                        }

                        if (found && deleteAfterFound)
                            queue.ReceiveById(msg.Id); //Remove from queue
                    }

                    return found;
                }
                catch (MessageQueueException msmqEx)
                {
                    if (msmqEx.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                        return false;
                    throw;
                }
            }
            /// <summary>
            /// Checks for an event being anywhere on the queue
            /// </summary>
            /// <param name="regEx"></param>
            /// <param name="includeBodyCompare"></param>
            /// <param name="timeoutSeconds"></param>
            /// <param name="deleteAfterFound"></param>
            /// <param name="queuePath"></param>
            /// <returns></returns>
            public static bool PeekForAnyEvent(string regEx, bool includeBodyCompare, int timeoutSeconds, bool deleteAfterFound, string queuePath)
            {
                bool found = false;
                DateTime timeout = DateTime.Now.AddSeconds(timeoutSeconds);

                var queue = new MessageQueue(queuePath);
                var e = queue.GetMessageEnumerator2();
                while (true)
                {
                    while (e.MoveNext())
                    {
                        var msg = e.Current;
                        if (msg != null)
                        {
                            if (Regex.IsMatch(msg.Label, regEx, RegexOptions.IgnoreCase))
                            {
                                Console.WriteLine(string.Format("Matching label: {0}", msg.Label));
                                found = true;
                            }

                            if (!found && includeBodyCompare)
                            {
                                msg.Formatter = new ActiveXMessageFormatter();
                                var body = msg.Body as string;
                                if (body != null)
                                    if (Regex.IsMatch(body, regEx, RegexOptions.IgnoreCase | RegexOptions.Multiline))
                                    {
                                        Console.WriteLine(string.Format("Matching Body: {0}", msg.Label));
                                        found = true;
                                    }
                            }

                            if (found && deleteAfterFound)
                                queue.ReceiveById(msg.Id);
                        }

                        if (found)
                            break;
                    }
                    if (found
                        || DateTime.Now > timeout)
                        break;
                }
                return found;
            }
        }
    }


